#include "ImagePreviewWidget.h"
#include "ui_ImagePreviewWidget.h"
#include <QUuid>
#include <QFileDialog>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QScrollArea>
#include <QPixmap>
#include <QApplication>
#include <QMessageBox>
#include <QDir>
#include <QDateTime>
#include <QCoreApplication>
#include "PreviewItem.h"

ImagePreviewWidget::ImagePreviewWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::ImagePreviewWidget)
    , m_cacheManager(nullptr)
    , m_buttonGroup(new QButtonGroup(this))
{
    // 设置无边框窗口
    setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);

    ui->setupUi(this);
    
    // 设置按钮组为互斥模式
    m_buttonGroup->setExclusive(true);
    
    // 初始化当前选中的GUID为空
    m_currentSelectedGuid = QString();
    
    // 连接UI按钮信号
    connect(ui->loadingPushButton, &QPushButton::clicked, this, &ImagePreviewWidget::handleLoadingButtonClick);
    connect(ui->savePushButton, &QPushButton::clicked, this, &ImagePreviewWidget::handleSaveButtonClick);
    
    // 初始化水平布局
    if (!ui->scrollAreaWidgetContents->layout()) {
        QHBoxLayout *layout = new QHBoxLayout(ui->scrollAreaWidgetContents);
        layout->setContentsMargins(0, 0, 0, 0);
        layout->setSpacing(10);
        ui->scrollAreaWidgetContents->setLayout(layout);
    }
    
    // 设置窗口可以接收键盘事件
    setFocusPolicy(Qt::StrongFocus);
}

ImagePreviewWidget::~ImagePreviewWidget()
{
    // 清理所有预览项
    m_previewItems.clear();
    delete m_buttonGroup;
    delete ui;
}

void ImagePreviewWidget::keyPressEvent(QKeyEvent *event)
{
    // 检查是否按下Ctrl+Z组合键
    if (event->modifiers() == Qt::ControlModifier && event->key() == Qt::Key_Z)
    {
        // 如果有选中的图像，发出撤销请求信号
        if (!m_currentSelectedGuid.isEmpty())
        {
            emit undoRequested(m_currentSelectedGuid);
        }
        // 接受这个事件，不再传递给父类
        event->accept();
    }
    // 检查是否按下Ctrl+Y组合键
    else if (event->modifiers() == Qt::ControlModifier && event->key() == Qt::Key_Y)
    {
        // 如果有选中的图像，发出重做请求信号
        if (!m_currentSelectedGuid.isEmpty())
        {
            emit redoRequested(m_currentSelectedGuid);
        }
        // 接受这个事件，不再传递给父类
        event->accept();
    }
    else
    {
        // 如果不是我们关心的快捷键组合，交给父类处理
        QWidget::keyPressEvent(event);
    }
}

void ImagePreviewWidget::setCacheManager(ImageCacheManager* cacheManager)
{
    // 断开旧缓存管理器的连接
    if (m_cacheManager) {
        disconnect(m_cacheManager, &ImageCacheManager::imageAdded, this, &ImagePreviewWidget::onImageAdded);
        disconnect(m_cacheManager, &ImageCacheManager::imageUpdated, this, &ImagePreviewWidget::onImageUpdated);
        disconnect(m_cacheManager, &ImageCacheManager::imageRemoved, this, &ImagePreviewWidget::onImageRemoved);
    }
    
    // 设置新的缓存管理器
    m_cacheManager = cacheManager;
    
    // 连接新缓存管理器的信号
    if (m_cacheManager) {
        connect(m_cacheManager, &ImageCacheManager::imageAdded, this, &ImagePreviewWidget::onImageAdded);
        connect(m_cacheManager, &ImageCacheManager::imageUpdated, this, &ImagePreviewWidget::onImageUpdated);
        connect(m_cacheManager, &ImageCacheManager::imageRemoved, this, &ImagePreviewWidget::onImageRemoved);
    }
}

QString ImagePreviewWidget::addImage(const QImage& newImage)
{
    if (!m_cacheManager || newImage.isNull())
    {
        qWarning() <<"添加的图片无效或缓存管理器未初始化";
        return QString();
    }

    // 生成临时文件路径用于缓存管理
    QString tempFilePath = QString("temp_image_%1.png").arg(QUuid::createUuid().toString(QUuid::Id128));
    newImage.save(tempFilePath);
    
    // 添加到缓存
    QString imageGuid = m_cacheManager->addImageToCache(tempFilePath);
    
    // 删除临时文件
    QFile::remove(tempFilePath);
    
    return imageGuid;
}

QString ImagePreviewWidget::loadImageFromFile(const QString &filePath)
{
    if (!m_cacheManager) {
        qWarning() << "缓存管理器未初始化";
        return QString();
    }
    
    // 检查文件是否存在
    if (!QFile::exists(filePath)) {
        qWarning() << "文件不存在:" << filePath;
        return QString();
    }
    
    // 添加到缓存
    QString imageGuid = m_cacheManager->addImageToCache(filePath);
    
    return imageGuid;
}

QImage ImagePreviewWidget::getImage(const QString &imageGuid) const
{
    if (m_cacheManager && m_cacheManager->containsImage(imageGuid)) {
        return m_cacheManager->getDisplayImage(imageGuid);
    }
    return QImage();
}

ImageCacheManager* ImagePreviewWidget::getCacheManager() const
{
    return m_cacheManager;
}

void ImagePreviewWidget::handleLoadingButtonClick()
{
    // 打开文件选择对话框
    QString filePath = QFileDialog::getOpenFileName(
        this,
        tr("打开图像文件"),
        QString(),
        tr("图像文件 (*.png *.jpg *.jpeg *.bmp *.tif *.tiff);;所有文件 (*.*)")
    );
    
    if (!filePath.isEmpty()) {
        // 加载图像到缓存
        QString imageGuid = loadImageFromFile(filePath);
        
        if (!imageGuid.isEmpty()) {
            // 发出注册请求信号
            emit requestRegisterImageDisplay(imageGuid);
        } else {
            QMessageBox::warning(this, tr("加载失败"), tr("无法加载图像文件"));
        }
    }
}

void ImagePreviewWidget::handleSaveButtonClick()
{
    if(m_currentSelectedGuid.isEmpty())
    {
        return;
    }
    
    // 获取图像
    QImage image = m_cacheManager->getDisplayImage(m_currentSelectedGuid);
    
    if (image.isNull()) {
        QMessageBox::warning(this, tr("保存失败"), tr("图像为空"));
        return;
    }
    
    // 生成默认保存路径和文件名
    QString savePath = m_cacheManager->getDefaultSavePath() + "/" + 
                      QString("image_%1.%2").arg(
                          QDateTime::currentDateTime().toString("yyyyMMdd_HHmmss_zzz"),
                          m_cacheManager->getDefaultSaveFormat()
                      );
    
    // 直接使用默认路径保存，不弹出文件选择对话框
    if (m_cacheManager->saveImageWithParams(m_currentSelectedGuid, savePath)) {
        QMessageBox::information(this, tr("保存成功"), tr("图像及参数已成功保存到:\n%1").arg(savePath));
    } else {
        QMessageBox::warning(this, tr("保存失败"), tr("无法保存图像及参数"));
    }
}


void ImagePreviewWidget::onImageAdded(const QString &imageGuid)
{
    // Add to image GUID list
    if (m_previewItems.contains(imageGuid)||!m_cacheManager->containsImage(imageGuid))
    {
        return;
    }

    m_currentSelectedGuid=imageGuid;
    QImage image = m_cacheManager->getDisplayImage(imageGuid);
    // 创建新的预览项
    PreviewItem *previewItem = new PreviewItem(this);
    previewItem->setImage(image);
    previewItem->setImageGuid(imageGuid);

    // 连接删除信号
    connect(previewItem, &PreviewItem::deleteRequested, m_cacheManager, &ImageCacheManager::removeImageFromCache);

    // 连接点击信号
    connect(previewItem, &PreviewItem::selectImageRequested, this, &ImagePreviewWidget::onPreviewItemClicked);

    // 添加到按钮组（互斥组）
    m_buttonGroup->addButton(previewItem);

    // 添加到布局和映射
    ui->horizontalLayout_ScrollAreaWidgetContents->insertWidget(ui->horizontalLayout_ScrollAreaWidgetContents->count()-1,previewItem);
    m_previewItems[imageGuid] = previewItem;

    // 调整布局
    ui->scrollAreaWidgetContents->layout()->update();
    previewItem->setChecked(true);
}

void ImagePreviewWidget::onImageRemoved(const QString &imageGuid)
{
    // 如果移除的是当前选中的图像，清除选中状态
    if (m_currentSelectedGuid == imageGuid) {
        m_currentSelectedGuid = QString();
    }
    
    // 单独移除对应的预览项，而不是更新整个区域
    if (m_previewItems.contains(imageGuid))
    {
        PreviewItem *previewItem = m_previewItems.take(imageGuid);
        // 从按钮组中移除
        m_buttonGroup->removeButton(previewItem);
        ui->scrollAreaWidgetContents->layout()->removeWidget(previewItem);
        // 发射预览项删除信号
        emit PreviewItemDelete(imageGuid);
        delete previewItem;
        // 调整布局
        ui->scrollAreaWidgetContents->layout()->update();
    }
}

void ImagePreviewWidget::onImageUpdated(const QString &imageGuid)
{
    // 单独更新对应的预览项，而不是更新整个区域
    if (m_previewItems.contains(imageGuid)) {
        QImage image = m_cacheManager->getDisplayImage(imageGuid);
        if (!image.isNull()) {
            m_previewItems[imageGuid]->setImage(image);
        }
    }
}

QString ImagePreviewWidget::getCurrentSelectedGuid() const
{
    return m_currentSelectedGuid;
}

void ImagePreviewWidget::setSelectedImageGuid(const QString &guid)
{
    if(m_currentSelectedGuid == guid)
    {
        return;
    }
    
    // 更新当前选中的GUID
    m_currentSelectedGuid = guid;
    
    // 设置属性，让外部可以访问
    setProperty("currentSelectedGuid", guid);
    
    // 通过按钮组设置选中项
    if (m_previewItems.contains(guid)) {
        m_previewItems[guid]->setChecked(true);
    }
}

void ImagePreviewWidget::updatePreviewArea()
{
    // 清空现有预览项（仅在初始化或特殊情况下使用）
    QLayout *layout = ui->scrollAreaWidgetContents->layout();
    if (layout) {
        // 移除所有预览项，但保留弹簧
        QLayoutItem *item;
        while ((item = layout->takeAt(0)) != nullptr) {
            if (item->widget()) {
                delete item->widget();
            }
            delete item;
        }
    }
    
    // 清空映射
    m_previewItems.clear();
    
    // 重建所有预览项（仅在初始化或特殊情况下使用）
    QStringList allImageGuids= m_cacheManager->getAllImageGuids();
    for (const QString &imageGuid : allImageGuids) {
        QImage image = m_cacheManager->getDisplayImage(imageGuid);
        if (!image.isNull()) {
            // 使用新的PreviewItem类
            PreviewItem *previewItem = new PreviewItem(this);
            previewItem->setImage(image);
            previewItem->setImageGuid(imageGuid);
            
            // 连接删除信号
            connect(previewItem, &PreviewItem::deleteRequested, m_cacheManager, &ImageCacheManager::removeImageFromCache);
            
            // 连接点击信号
            connect(previewItem, &PreviewItem::selectImageRequested, this, &ImagePreviewWidget::onPreviewItemClicked);
            
            ui->scrollAreaWidgetContents->layout()->addWidget(previewItem);
            m_previewItems[imageGuid] = previewItem;
        }
    }
    
    // 添加弹簧使图像从最左边开始显示
    QHBoxLayout *previewLayout = qobject_cast<QHBoxLayout*>(ui->scrollAreaWidgetContents->layout());
    if (previewLayout) {
        previewLayout->addStretch();
    }
    
    // 调整布局
    ui->scrollAreaWidgetContents->layout()->update();
}

void ImagePreviewWidget::onPreviewItemClicked(const QString &guid)
{
    if(m_currentSelectedGuid==guid)
    {
        return;
    }
    // 发出switchToGraphicsDisplayWidget信号，通知切换到对应的图形显示窗口
    emit switchToPreviewItem(guid);
}
